import { useState, useCallback, useRef, useEffect } from 'react';
import ReactFlow, {
  MiniMap,
  Controls,
  Background,
  useNodesState,
  useEdgesState,
  addEdge,
  MarkerType
} from 'reactflow';
import 'reactflow/dist/style.css';
import yaml from 'js-yaml';
import './App.css';

// 组件类型定义
const componentTypes = [
  {
    id: 'DataLoader',
    label: '数据加载器',
    description: '加载CSV或JSON数据',
    defaultConfig: {
      data_path: '',
      sample_size: 1000
    }
  },
  {
    id: 'DataContinuity',
    label: '数据完整性检测',
    description: '检查数据连续性',
    defaultConfig: {
      column_name: 'timestamp',
      interval: 60
    }
  },
  {
    id: 'DataEmptyValue',
    label: '空值检测',
    description: '检测数据中的空值',
    defaultConfig: {}
  },
  {
    id: 'DataOutOfRange',
    label: '数据范围检测',
    description: '检测数据是否在合理范围内',
    defaultConfig: {
      column_names: [],
      threshold_range: []
    }
  },
  {
    id: 'DataMeanStatistics',
    label: '均值统计',
    description: '计算数据均值',
    defaultConfig: {
      column_names: []
    }
  },
  {
    id: 'DataMedianStatistics',
    label: '中位数统计',
    description: '计算数据中位数',
    defaultConfig: {
      column_names: []
    }
  },
  {
    id: 'DataStdStatistics',
    label: '标准差统计',
    description: '计算数据标准差',
    defaultConfig: {
      column_names: []
    }
  },
  {
    id: 'DataSkewnessStatistics',
    label: '偏度统计',
    description: '计算数据偏度',
    defaultConfig: {
      column_names: []
    }
  },
  {
    id: 'DataKurtosisStatistics',
    label: '峰度统计',
    description: '计算数据峰度',
    defaultConfig: {
      column_names: []
    }
  }
];

// 不使用自定义节点，直接使用ReactFlow的默认节点类型以确保连接功能正常
const nodeTypes = {};

function App() {
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);
  const [selectedNode, setSelectedNode] = useState(null);
  const [selectedEdge, setSelectedEdge] = useState(null);
  const [isYamlView, setIsYamlView] = useState(false);
  const [globalConfig, setGlobalConfig] = useState({
    max_concurrent_tasks: 5,
    pipeline_timeout: 300.0,
    resources: {
      default_task_resources: {
        cpu_limit: 1.0,
        memory_limit: '1G',
        thread_limit: 2
      }
    }
  });
  const reactFlowWrapper = useRef(null);
  const nodeIdCounter = useRef(1);
  const reactFlowInstance = useRef(null);

  // 处理节点选择
  const onNodeClick = useCallback((event, node) => {
    setSelectedNode(node);
    setSelectedEdge(null); // 点击节点时清除边的选中状态
  }, []);
  
  // 处理边选择
  const onEdgeClick = useCallback((event, edge) => {
    event.preventDefault(); // 阻止事件冒泡到背景
    setSelectedEdge(edge);
    setSelectedNode(null); // 点击边时清除节点的选中状态
  }, []);
  
  // 处理删除节点
  const deleteSelectedNode = useCallback(() => {
    if (!selectedNode) return;
    
    // 删除相关的边
    const updatedEdges = edges.filter(edge => 
      edge.source !== selectedNode.id && edge.target !== selectedNode.id
    );
    setEdges(updatedEdges);
    
    // 删除节点
    setNodes(prevNodes => prevNodes.filter(node => node.id !== selectedNode.id));
    setSelectedNode(null);
  }, [selectedNode, edges]);
  
  // 处理删除边
  const deleteSelectedEdge = useCallback(() => {
    if (!selectedEdge) return;
    
    // 从edges数组中删除选中的边
    setEdges(prevEdges => prevEdges.filter(edge => edge.id !== selectedEdge.id));
    setSelectedEdge(null);
  }, [selectedEdge]);
  
  // 监听键盘事件处理删除
  useEffect(() => {
    const handleKeyDown = (event) => {
      if (event.key === 'Delete') {
        if (selectedNode) {
          deleteSelectedNode();
        } else if (selectedEdge) {
          deleteSelectedEdge();
        }
      }
    };
    
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [selectedNode, deleteSelectedNode, selectedEdge, deleteSelectedEdge]);

  // 处理连线创建
  const onConnect = useCallback(
    (params) => 
      setEdges((eds) => 
        addEdge(
          {
            ...params,
            type: 'smoothstep',
            animated: true,
            markerEnd: {
              type: MarkerType.ArrowClosed,
              width: 16,
              height: 16
            }
          },
          eds
        )
      ),
    []
  );

  // 处理配置更新
  const handleConfigChange = (key, value) => {
    if (selectedNode) {
      const updatedNodes = nodes.map(node => {
        if (node.id === selectedNode.id) {
          return {
            ...node,
            data: {
              ...node.data,
              config: {
                ...node.data.config,
                [key]: value
              }
            }
          };
        }
        return node;
      });
      setNodes(updatedNodes);
      setSelectedNode(updatedNodes.find(n => n.id === selectedNode.id));
    }
  };

  // 处理资源配置更新
  const handleResourceChange = (key, value) => {
    if (selectedNode) {
      const updatedNodes = nodes.map(node => {
        if (node.id === selectedNode.id) {
          return {
            ...node,
            data: {
              ...node.data,
              resources: {
                ...node.data.resources,
                [key]: value
              }
            }
          };
        }
        return node;
      });
      setNodes(updatedNodes);
      setSelectedNode(updatedNodes.find(n => n.id === selectedNode.id));
    }
  };

  // 处理全局配置更新
  const handleGlobalConfigChange = (path, value) => {
    const newConfig = { ...globalConfig };
    if (path.includes('.')) {
      const [parent, child] = path.split('.');
      newConfig[parent] = {
        ...newConfig[parent],
        [child]: value
      };
    } else {
      newConfig[path] = value;
    }
    setGlobalConfig(newConfig);
  };

  // 处理组件拖拽到画布
  const handleDragOver = (event) => {
    event.preventDefault();
    event.dataTransfer.dropEffect = 'move';
  };

  const handleDrop = (event) => {
    event.preventDefault();
    const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
    const type = event.dataTransfer.getData('application/reactflow');
    const componentType = componentTypes.find(ct => ct.id === type);

    if (!type || !componentType || !reactFlowWrapper.current) return;
    
    // 获取ReactFlow实例
    const flowInstance = reactFlowInstance.current;
    
    // 计算精确的位置
    let position;
    
    // 使用ReactFlow实例的坐标转换方法（如果可用）
    if (flowInstance) {
      // 直接使用ReactFlow的坐标转换方法
      // 计算相对于ReactFlow容器的鼠标位置
      const relativeX = event.clientX - reactFlowBounds.left;
      const relativeY = event.clientY - reactFlowBounds.top;
      
      // 获取当前视图状态
      const viewport = flowInstance.getViewport();
      
      // 计算正确的画布坐标，考虑缩放和偏移
      position = {
        x: (relativeX - viewport.x) / viewport.zoom,
        y: (relativeY - viewport.y) / viewport.zoom
      };
    } else {
      // 备选方案：直接计算相对于容器的位置
      position = {
        x: event.clientX - reactFlowBounds.left,
        y: event.clientY - reactFlowBounds.top
      };
    }
    
    // 创建新节点，使用组件名+序号作为ID
    const newNode = {
      id: `${componentType.id.toLowerCase()}_${nodeIdCounter.current++}`,
      // 不指定type使用默认节点类型
      position,
      // 必须设置源和目标位置
      sourcePosition: 'right',
      targetPosition: 'left',
      // 设置节点内容
      data: {
        label: `${componentType.label}\n(${componentType.id})`,
        plugin_type: componentType.id,
        config: { ...componentType.defaultConfig },
        resources: {
          cpu_limit: 2.0,
          memory_limit: '1.5G',
          thread_limit: 4
        }
      }
    };

    setNodes((prevNodes) => [...prevNodes, newNode]);
  };

  // 导出为YAML
  const exportToYaml = () => {
    const pipelineConfig = {
      global_config: globalConfig,
      nodes: {},
      edges: []
    };

    // 转换节点
    nodes.forEach(node => {
      pipelineConfig.nodes[node.id] = {
        plugin_type: node.data.plugin_type,
        resources: node.data.resources,
        config: node.data.config
      };
    });

    // 转换边
    edges.forEach(edge => {
      pipelineConfig.edges.push({
        from: edge.source,
        to: edge.target
      });
    });

    return yaml.dump(pipelineConfig, {
      indent: 2,
      lineWidth: -1
    });
  };

  // 复制YAML
  const copyYaml = () => {
    navigator.clipboard.writeText(exportToYaml());
    alert('YAML已复制到剪贴板');
  };

  // 下载YAML
  const downloadYaml = () => {
    const blob = new Blob([exportToYaml()], { type: 'application/x-yaml' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'pipeline_config.yaml';
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div className="app-container">
      <header className="app-header">
        <h1>数据质量任务编排平台</h1>
        <div className="header-actions">
          <button onClick={() => setIsYamlView(!isYamlView)}>
            {isYamlView ? '可视化视图' : 'YAML视图'}
          </button>
        </div>
      </header>
      
      <div className="main-content">
        <aside className="left-panel">
          <h2>组件库</h2>
          <div className="components-list">
            {componentTypes.map((component) => (
              <div
                key={component.id}
                className="component-item"
                draggable
                onDragStart={(e) => {
                  e.dataTransfer.setData('application/reactflow', component.id);
                }}
              >
                <h3>{component.label}</h3>
                <p>{component.description}</p>
              </div>
            ))}
          </div>
        </aside>

        <main className="canvas-container">
          {!isYamlView ? (
            <div className="reactflow-wrapper" ref={reactFlowWrapper}>
              <ReactFlow
                  nodes={nodes}
                  edges={edges}
                  onNodesChange={onNodesChange}
                  onEdgesChange={onEdgesChange}
                  onConnect={onConnect}
                  onNodeClick={onNodeClick}
                  onEdgeClick={onEdgeClick}
                  onDragOver={handleDragOver}
                  onDrop={handleDrop}
                  fitView
                  onInit={instance => reactFlowInstance.current = instance}
                  // 核心配置，确保连接功能正常
                  defaultEdgeOptions={{
                    type: 'smoothstep',
                    animated: true,
                    markerEnd: {
                      type: MarkerType.ArrowClosed,
                      width: 16,
                      height: 16
                    }
                  }}
                  // 确保连接手柄默认可见
                  fitViewOptions={{
                    padding: 0.1
                  }}
                >
                <Controls />
                <MiniMap />
                <Background variant="dots" gap={12} size={1} />
              </ReactFlow>
            </div>
          ) : (
            <div className="yaml-view">
              <div className="yaml-header">
                <h3>YAML配置</h3>
                <div className="yaml-actions">
                  <button onClick={copyYaml}>复制YAML</button>
                  <button onClick={downloadYaml}>下载YAML</button>
                </div>
              </div>
              <pre className="yaml-content">{exportToYaml()}</pre>
            </div>
          )}
        </main>

        <aside className="right-panel">
          {selectedNode ? (
            <div className="node-details">
              <h2>节点配置</h2>
              <div className="detail-section">
                <h3>基本信息</h3>
                <div className="form-group">
                  <label>组件类型</label>
                  <input 
                    type="text" 
                    value={selectedNode.data.plugin_type} 
                    disabled 
                  />
                </div>
                <div className="form-group">
                  <label>组件ID</label>
                  <input 
                    type="text" 
                    value={selectedNode.id} 
                    disabled 
                  />
                </div>
                <button 
                  className="delete-button" 
                  onClick={deleteSelectedNode}
                >
                  删除节点
                </button>
              </div>
              <div className="detail-section">
                <h3>资源配置</h3>
                <div className="form-group">
                  <label>CPU限制</label>
                  <input
                    type="number"
                    value={selectedNode.data.resources?.cpu_limit || 1}
                    onChange={(e) => handleResourceChange('cpu_limit', parseFloat(e.target.value))}
                  />
                </div>
                <div className="form-group">
                  <label>内存限制</label>
                  <input
                    type="text"
                    value={selectedNode.data.resources?.memory_limit || '1G'}
                    onChange={(e) => handleResourceChange('memory_limit', e.target.value)}
                  />
                </div>
                <div className="form-group">
                  <label>线程限制</label>
                  <input
                    type="number"
                    value={selectedNode.data.resources?.thread_limit || 1}
                    onChange={(e) => handleResourceChange('thread_limit', parseInt(e.target.value))}
                  />
                </div>
              </div>
              <div className="detail-section">
                <h3>组件配置</h3>
                {Object.entries(selectedNode.data.config || {}).map(([key, value]) => (
                  <div key={key} className="form-group">
                    <label>{key}</label>
                    {typeof value === 'string' || typeof value === 'number' ? (
                      <input
                        type={typeof value === 'number' ? 'number' : 'text'}
                        value={value}
                        onChange={(e) => {
                          const newValue = typeof value === 'number' ? 
                            (key.includes('interval') ? parseInt(e.target.value) : parseFloat(e.target.value)) : 
                            e.target.value;
                          handleConfigChange(key, newValue);
                        }}
                      />
                    ) : (
                      <textarea
                        value={JSON.stringify(value)}
                        onChange={(e) => {
                          try {
                            handleConfigChange(key, JSON.parse(e.target.value));
                          } catch (e) {
                            console.error('Invalid JSON');
                          }
                        }}
                      />
                    )}
                  </div>
                ))}
              </div>
            </div>
          ) : selectedEdge ? (
            <div className="edge-details">
              <h2>连接线详情</h2>
              <div className="detail-section">
                <h3>连接信息</h3>
                <div className="form-group">
                  <label>源节点</label>
                  <input 
                    type="text" 
                    value={selectedEdge.source} 
                    disabled 
                  />
                </div>
                <div className="form-group">
                  <label>目标节点</label>
                  <input 
                    type="text" 
                    value={selectedEdge.target} 
                    disabled 
                  />
                </div>
                <button 
                  className="delete-button" 
                  onClick={deleteSelectedEdge}
                >
                  删除连接线
                </button>
              </div>
            </div>
          ) : (
            <>
              <div className="empty-state">
                <p>选择一个节点或连接线来配置其属性</p>
              </div>
              <div className="global-properties">
                <h2>全局配置</h2>
                <div className="property">
                  <label>最大并发任务数:</label>
                  <input
                    type="number"
                    value={globalConfig.max_concurrent_tasks}
                    onChange={(e) => handleGlobalConfigChange('max_concurrent_tasks', parseInt(e.target.value))}
                  />
                </div>
                <div className="property">
                  <label>Pipeline执行超时时间(秒):</label>
                  <input
                    type="number"
                    value={globalConfig.pipeline_timeout}
                    onChange={(e) => handleGlobalConfigChange('pipeline_timeout', parseFloat(e.target.value))}
                  />
                </div>
                <div className="property-group">
                  <h3>默认资源配置</h3>
                  <div className="property">
                    <label>CPU限制:</label>
                    <input
                      type="number"
                      value={globalConfig.resources.default_task_resources.cpu_limit}
                      onChange={(e) => handleGlobalConfigChange('resources.default_task_resources.cpu_limit', parseFloat(e.target.value))}
                    />
                  </div>
                  <div className="property">
                    <label>内存限制:</label>
                    <input
                      type="text"
                      value={globalConfig.resources.default_task_resources.memory_limit}
                      onChange={(e) => handleGlobalConfigChange('resources.default_task_resources.memory_limit', e.target.value)}
                    />
                  </div>
                  <div className="property">
                    <label>线程限制:</label>
                    <input
                      type="number"
                      value={globalConfig.resources.default_task_resources.thread_limit}
                      onChange={(e) => handleGlobalConfigChange('resources.default_task_resources.thread_limit', parseInt(e.target.value))}
                    />
                  </div>
                </div>
              </div>
            </>
          )}
        </aside>
      </div>
    </div>
  );
}

export default App;
